package com.infinit.selfhelp.common.base

import android.os.Bundle
import android.util.Log
import android.view.View
import android.view.View.OnClickListener
import androidx.activity.OnBackPressedCallback
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import com.drake.channel.receiveEvent
import com.infinit.selfhelp.common.loading.CommonLoadingDelegate
import com.infinit.selfhelp.common.loading.ILoadingDelegate
import com.infinit.selfhelp.common.loading.LoadingDialogManager
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

abstract class ViewBindingFragment<B : ViewDataBinding> : Fragment, LoadingDialogManager {
    constructor() : super()
    constructor(contentLayoutId: Int) : super(contentLayoutId)

    companion object {
        private const val DELAY_MILLIS = 2 * 60 * 1000L // 2 * 60 * 1000L // 2 minutes in milliseconds
    }

    private var logJob: Job? = null
    private var hasLogged = false


    val mBinding: B
        get() {
            return DataBindingUtil.bind(requireView())!!
        }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        initData()
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        DataBindingUtil.bind<B>(view)
        try {
            initView()
            onEvent()
            observe()
            receiveEvent<BaseViewModel.LoadingEvent>(lifeEvent = Lifecycle.Event.ON_STOP) {
                if (it.isShow) {
                    showLoadingDialog(requireContext())
                } else {
                    hideLoadingDialog()
                }
            }

        } catch (_: Exception) {
        }
    }

    open fun initData() {}
    open fun initView() {}

    open fun observe() {}
    abstract fun onEvent()

    fun addOnBackPressed(
        owner: LifecycleOwner,
        onBackPressed: () -> Boolean,
    ): OnBackPressedCallback {
        val callback = object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                if (!onBackPressed()) {
                    isEnabled = false
                    requireActivity().onBackPressedDispatcher.onBackPressed()
                    isEnabled = true
                }
            }
        }
        requireActivity().onBackPressedDispatcher.addCallback(owner, callback)
        return callback
    }

    val back = OnClickListener {
        requireActivity().onBackPressed()
    }
    override val loadingDelegate: ILoadingDelegate by lazy {
        CommonLoadingDelegate()
    }

    fun startLoggingTimer(delayTime: Long = 0, action: () -> Unit) {
        // Reset the logged flag each time the fragment resumes
        hasLogged = false

        // Cancel any existing job
        logJob?.cancel()

        // Start a new coroutine for the timer
        logJob = viewLifecycleOwner.lifecycleScope.launch {
            delay(if (delayTime == 0L) DELAY_MILLIS else delayTime)
            if (!hasLogged) {
                Log.d("MyFragment", "Page has been active for 2 minutes.")
                hasLogged = true
                action()
            }
        }
    }

    fun stopLoggingTimer() {
        // Cancel the coroutine job to stop the timer
        logJob?.cancel()
    }

}
